// https://www.jianshu.com/p/8aa08cd62b04
// 判断二代身份证信息
// 定义symbol
const _code = Symbol('code')

//省份代码对应的名称对应对象
const province = {
  11: '北京市',
  12: '天津市',
  13: '河北省',
  14: '山西省',
  15: '内蒙古自治区',
  21: '辽宁省',
  22: '吉林省',
  23: '黑龙江省',
  31: '上海市',
  32: '江苏省',
  33: '浙江省',
  34: '安徽省',
  35: '福建省',
  36: '江西省',
  37: '山东省',
  41: '河南省',
  42: '湖北省',
  43: '湖南省',
  44: '广东省',
  45: '广西壮族自治区',
  46: '海南省',
  50: '重庆市',
  51: '四川省',
  52: '贵州省',
  53: '云南省',
  54: '西藏自治区',
  61: '陕西省',
  62: '甘肃省',
  63: '青海省',
  64: '宁夏回族自治区',
  65: '新疆维吾尔自治区',
  71: '台湾省',
  81: '香港特别行政区',
  82: '澳门特别行政区'
}

/**
 * 第二代身份证对象
 * * 没有加市级和区级的名称提取，信息太过庞大，且每年都有在变更，
 * * 这种数据还是放在后端比较合适，如果真的需要，自行扩展，数据可以直接去爬政府公布的，地址：http://www.mca.gov.cn/article/sj/xzqh/1980/
 * @author 927552837@qq.com
 */
class IdCode {
  /**
     * @param {code} 传入身份证号码
     * 构造函数
     */
  constructor(code) {
    // 利用symbol声明私有变量
    this[_code] = code
  }

  /**
     * 校验身份证号码是否正确
     * 要注意的是，校验码校验通过并不代表身份证不是伪造的，校验码的作用是为了防止填写出错
     */
  isCheck() {
    const code = this[_code]
    //先使用正则校验
    var reg = /(^[1-9]\d{5}(18|19|([23]\d))\d{2}((0[1-9])|(10|11|12))(([0-2][1-9])|10|20|30|31)\d{3}[0-9Xx]$)|(^[1-9]\d{5}\d{2}((0[1-9])|(10|11|12))(([0-2][1-9])|10|20|30|31)\d{3}$)/
    if (!reg.test(code)) {
      //格式不正确
      return false
    }
    //再使用校验码校验
    //西格玛Ai*Wi
    let leftNum = 0
    //加权因子 公式：Wi = 2^(i-1) mod 11
    const Wi = [7, 9, 10, 5, 8, 4, 2, 1, 6, 3, 7, 9, 10, 5, 8, 4, 2, 1]
    for (let i = 0; i < code.length; i++) {
      //第18位如果是X则把计算数值改为10
      if (i === 17 && (code[i] === 'X' || code[i] === 'x')) {
        leftNum += 10 * Wi[i]
      } else {
        leftNum += code[i] * Wi[i]
      }
    }
    //结果判断
    if (leftNum % 11 !== 1) {
      return false
    } else {
      return true
    }
  }

  /**
     * 获取身份证号码
     */
  getCode() {
    return this[_code]
  }

  /**
     * 获取省代码
     */
  getProvinceCode() {
    return this[_code].substr(0, 2)
  }

  /**
     * 获取省名称
     */
  getProvinceName() {
    //获取省代码
    const provinceCode = this.getProvinceCode()
    return province[provinceCode]
  }

  /**
     * 获取市代码
     */
  getCityCode() {
    return this[_code].substr(0, 4)
  }

  /**
     * 获取区代码
     */
  getAreaCode() {
    return this[_code].substr(0, 6)
  }

  /**
     * 获取年
     */
  getYears() {
    return this[_code].substr(6, 4)
  }

  /**
     * 获取月
     */
  getMonth() {
    return this[_code].substr(10, 2)
  }

  /**
     * 获取日
     */
  getDay() {
    return this[_code].substr(12, 2)
  }

  /**
     * 获取生日
     * @return {Date}
     */
  getBirthday() {
    //得到日期字符串
    const dateStr = this.getYears() + '/' + this.getMonth() + '/' + this.getDay()
    return new Date(dateStr)
  }

  /**
     * 获取性别
     */
  getGender() {
    return this[_code].substr(16, 1) % 2 === 0 ? '女' : '男'
  }
}

//对外对象
const idCode = {
  //构造对象
  createNew (code) {
    return new IdCode(code)
  }
}

export default idCode
